/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wads.app.control;

import java.awt.Point;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import wads.com.UserInfo;
import wads.drawing.CaseShape;
import wads.drawing.line.WADLink;
import wads.drawing.node.CaseNode;
import wads.drawing.node.DatabaseNode;
import wads.drawing.node.DocumentNode;
import wads.drawing.node.GateNode;
import wads.drawing.node.UserNode;

/**
 *
 * @author ManowTangdud
 */
public class WADSXMLImporter {
    private Document templateXMLDoc;
    private UserInfo userInfo;

    public WADSXMLImporter(UserInfo userInfo) {
        this.userInfo = userInfo;
    }

    public Vector<CaseShape> importXMLFile(File xpdlfile) {
        try {
            Vector<CaseShape> drawobject = new Vector<CaseShape>();
            CaseNode start = null, end = null;

            templateXMLDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xpdlfile);
            NodeList activitylist = templateXMLDoc.getElementsByTagName(WADSXMLExporter.ACTIVITY);
            NodeList transitionlist = templateXMLDoc.getElementsByTagName(WADSXMLExporter.TRANSITION);
            String docpath = ((Element)templateXMLDoc.getElementsByTagName(WADSXMLExporter.DOCUMENTATION).item(0)).getTextContent();
            String xpdlVersion = ((Element)templateXMLDoc.getElementsByTagName(WADSXMLExporter.XPDLVERSION).item(0)).getTextContent();
            String created = ((Element)templateXMLDoc.getElementsByTagName(WADSXMLExporter.CREATED).item(0)).getTextContent();
            String description = ((Element)templateXMLDoc.getElementsByTagName(WADSXMLExporter.DESCRIPTION).item(0)).getTextContent();
            String documentId = ((Element)templateXMLDoc.getElementsByTagName(WADSXMLExporter.WORKFLOW_PROCESS).item(0)).getAttribute(WADSXMLExporter.ID_ATTR);
            Element tempnode;
            Element tempcoor;

            Element templink;

            for(int i=0;i<activitylist.getLength();i++) {
                tempnode = (Element)activitylist.item(i);
                //System.out.println(tempnode.getElementsByTagName(WADSXMLExporter.COORDINATES).item(0).getNodeName());
                tempcoor = (Element)tempnode.getElementsByTagName(WADSXMLExporter.COORDINATES).item(0);
                Point coor = new Point(Integer.parseInt(tempcoor.getAttribute(WADSXMLExporter.XCOORDINATE_ATTR)), Integer.parseInt(tempcoor.getAttribute(WADSXMLExporter.YCOORDINATE_ATTR)));

                if(tempnode.getAttribute(WADSXMLExporter.START_ACTIVITY_ATTR).equals("true")) {
                    System.out.println("id: "+tempnode.getAttribute(WADSXMLExporter.ID_ATTR)+" this node is Document.");
                    DocumentNode doc = new DocumentNode(coor);
                    doc.setId(Integer.parseInt(tempnode.getAttribute(WADSXMLExporter.ID_ATTR)));
                    doc.setName(tempnode.getAttribute(WADSXMLExporter.NAME_ATTR));
                    doc.setPrototypePath(docpath);
                    doc.setXPDLVersion(xpdlVersion);
                    doc.setCreated(created);
                    doc.setDescription(description);
                    doc.setDocumentId(documentId);
                    drawobject.addElement(doc);
                }
                else if(tempnode.getAttribute(WADSXMLExporter.NAME_ATTR).equals("Database")) {
                    System.out.println("id: "+tempnode.getAttribute(WADSXMLExporter.ID_ATTR)+" this node is Database.");
                    DatabaseNode db = new DatabaseNode(coor);
                    db.setId(Integer.parseInt(tempnode.getAttribute(WADSXMLExporter.ID_ATTR)));
                    drawobject.addElement(db);
                }
                else if(tempnode.getAttribute(WADSXMLExporter.NAME_ATTR).equals("Gate")) {
                    System.out.println("id: "+tempnode.getAttribute(WADSXMLExporter.ID_ATTR)+" this node is Gate.");
                    String gatetype = "";
                    Element transitionrestriction = (Element)tempnode.getElementsByTagName(WADSXMLExporter.JOIN).item(0);
                    if(transitionrestriction != null) {
                        gatetype = transitionrestriction.getAttribute(WADSXMLExporter.TYPE_ATTR);
                        System.out.println("Transition Restriction is JOIN");
                    }
                    transitionrestriction = (Element)tempnode.getElementsByTagName(WADSXMLExporter.SPLIT).item(0);
                    if(transitionrestriction != null) {
                        gatetype = transitionrestriction.getAttribute(WADSXMLExporter.TYPE_ATTR);
                        System.out.println("Transition Restriction is SPLIT");
                    }

                    GateNode gate = new GateNode(coor);
                    gate.setId(Integer.parseInt(tempnode.getAttribute(WADSXMLExporter.ID_ATTR)));
                    gate.setGateTypeWithString(gatetype);
                    drawobject.addElement(gate);
                }
                else {
                    System.out.println("id: "+tempnode.getAttribute(WADSXMLExporter.ID_ATTR)+" this node is User.");
                    UserNode user = new UserNode(coor);
                    user.setId(Integer.parseInt(tempnode.getAttribute(WADSXMLExporter.ID_ATTR)));
                    user.setUsername(tempnode.getAttribute(WADSXMLExporter.NAME_ATTR));
                    // NOTICE: Beware of return "null" when you call "UserInfo.getDataByUsername();"
                    user.setName(userInfo.getDataByUsername(tempnode.getAttribute(WADSXMLExporter.NAME_ATTR)).getName());
                    drawobject.addElement(user);
                }
            }

            System.out.println(transitionlist.getLength()+" links found.");
            for(int i=0;i<transitionlist.getLength();i++) {
                templink = (Element)transitionlist.item(i);
                int startid = Integer.parseInt(templink.getAttribute(WADSXMLExporter.FROM_ATTR));
                int endid = Integer.parseInt(templink.getAttribute(WADSXMLExporter.TO_ATTR));
                for(int j=0;j<drawobject.size();j++) {
                    if(drawobject.get(j) instanceof CaseNode && drawobject.get(j).getId() == startid) {
                        start = (CaseNode)drawobject.get(j);
                    }
                    if(drawobject.get(j) instanceof CaseNode && drawobject.get(j).getId() == endid) {
                        end = (CaseNode)drawobject.get(j);
                    }
                }
                
                WADLink link = new WADLink(start, end);
                System.out.println("link id: "+link.getId());
                System.out.println("start is "+start.getId());
                System.out.println("end is "+end.getId()+"\n");
                link.setId(Integer.parseInt(templink.getAttribute(WADSXMLExporter.ID_ATTR)));
                link.setName(templink.getAttribute(WADSXMLExporter.NAME_ATTR));

                Element condition = (Element)templink.getElementsByTagName(WADSXMLExporter.CONDITION).item(0);
                if(condition != null) {
                    link.setConditionType(condition.getAttribute(WADSXMLExporter.TYPE_ATTR));
                    link.setConditionExpression(condition.getTextContent());
                }

                drawobject.addElement(link);
            }

            return drawobject;
        }


        catch (ParserConfigurationException ex) {
            Logger.getLogger(WADSXMLExporter.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (SAXException ex) {
            Logger.getLogger(WADSXMLExporter.class.getName()).log(Level.SEVERE, null, ex);
        }
        catch (IOException ex) {
            Logger.getLogger(WADSXMLExporter.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
  }
}
